
function AccessRule ( addressCtrl, netmaskCtrl, ruleCtrl, propList )
{
	this.m_addressCtrl = addressCtrl ;
	this.m_netmaskCtrl = netmaskCtrl ;
	this.m_ruleCtrl = ruleCtrl ;
	this.m_propList = propList ;
	this.m_bAllowHostnames = true ;
	this.m_bAllowZero = false ;

	return this ;
}

AccessRule.prototype.AllowHostnames = function ( bAllowHostnames )
{
	if ( arguments.length )
	{
		this.m_bAllowHostnames = ( bAllowHostnames ? true : false );
	}
	return this.m_bAllowHostnames ;
}

// allow the address 0.0.0.0
AccessRule.prototype.AllowZero = function ( bAllowZero )
{
	if ( arguments.length )
	{
		this.m_bAllowZero = ( bAllowZero ? true : false );
	}
	return this.m_bAllowZero ;
}

AccessRule.prototype.split = function ()
{
	var address = "";
	var netmask = "";

	var rule = getCtrlValue( this.m_ruleCtrl );
	if ( rule.bSearch( "/" ) )
	{
		var tempA = rule.split( "/" );
		if ( tempA )
		{
			address = tempA[ 0 ];
			if ( ! isBlank( tempA[ 1 ] ) )
				netmask = tempA[ 1 ];
		}
	}
	else if ( rule.bSearch( ":" ) )
	{
		var tempA = rule.split( ":" );
		if ( tempA )
		{
			address = tempA[ 0 ];
			if ( ! isBlank( tempA[ 1 ] ) )
			{
				var ip = new IPAddress( tempA[ 1 ] );
				if ( ! ip.errMsg )
				{
					netmask = numBits( ip.addr );
				}
			}
		}
	}
	else
	{
		address = rule ;
	}

	setCtrlValue( this.m_addressCtrl, address );
	setCtrlValue( this.m_netmaskCtrl, netmask );
}

function numBits ( n )
{
    var strBinary = "";
    var remainder = n;

    while ( remainder >= 2 )
    {
        strBinary += remainder % 2;
        remainder = Math.floor( remainder / 2 );
    }
	strBinary += remainder;

	// out binary str is in reverse order, we don't care,
	// we just want the number of consecutive 1's at the end
	var aMatch = strBinary.match( /1+$/ );
 	return ( aMatch ? aMatch[ 0 ].length : "" );
}

AccessRule.prototype.validate = function ()
{
	// validate address as a proper ip address
	// stores in rule control if valid

	errMsgIP = "IP 地址必须在以下范围 [1-255].[0-255].[0-255].[0-255]" ;

	var bValid = false ;
	var addr = getCtrlValue( this.m_addressCtrl );
	var rule = addr ;

	// if the address is an IP address, makes sure its valid.
	// then, determine wether a netmask is needed
	if ( ! isIPAddrFormat( addr ) )
	{
		// do we allow hostnames?
		if ( ! this.m_bAllowHostnames )
		{
			return rejectInput( this.m_addressCtrl, errMsgIP );
		}

		// see if the hostname is valid
		if ( ! this.m_propList.hostname_validate( addr ) )
			return rejectInput( this.m_addressCtrl, this.m_propList.errMsg );

		// else hostname is good - no netmask needed
	}
	else if ( !isIPAddr( addr, this.m_bAllowZero ) )
	{
		// invalid IP Address
		return rejectInput( this.m_addressCtrl, errMsgIP );
	}
	else	// valid IP Address - see if the netmask is valid (and whether its needed or not)
	{
		// determine if a netmask is required: the address has a zero in it
		var needNetmask = false ;
		var octets = addr.split( '.' );
		for ( var i = 0; i < octets.length; i++ )
		{ 
			if ( parseInt( octets[ i ] ) == 0 )
			{
				needNetmask = true ;
				break ;
			}	
		}

		var netmask = getCtrlValue( this.m_netmaskCtrl );
		if ( needNetmask && ("" == netmask) )
		{
			return rejectInput( this.m_netmaskCtrl, "A netmask is required for this IP address." );
		}
		if ( "" != netmask )
		{
			if ( ! this.m_propList.netmask_validate( netmask ) )
				return rejectInput( this.m_netmaskCtrl, this.m_propList.errMsg );

			var seperator = ":" ;
			if ( -1 == netmask.indexOf( "." ) )
				seperator = "/" ;

			rule += seperator + netmask ;
		}
	}

	setCtrlValue( this.m_ruleCtrl, rule );

	return true ;
}

AccessRule.prototype.join = function ()
{
	var seperator = ":" ;

	var netmask = getCtrlValue( this.m_netmaskCtrl );
	if ( netmask == "" )
		seperator = "" ;
	else if ( parseInt( netmask ) == netmask )
		seperator = "/" ;

	setCtrlValue( this.m_ruleCtrl, 
		getCtrlValue( this.m_addressCtrl ) +
		seperator + netmask );
}


